"""
1. 定义类 ---> 银行账户 ---> 账户余额 / 存钱
2. 创建一个银行账户对象，启动100个线程，每个线程向该账户存入1元钱
3. 查询账户余额

多线程编程的坑点：
~ 当多个线程竞争一个资源的时候，如果没有适当保护措施，这个资源的状态很有可能出现问题
"""
import time
from threading import Thread, RLock


class Account:
    """银行账户"""

    def __init__(self):
        self.balance = 0
        self.lock = RLock()

    def deposit(self, amount):
        """存钱"""
        # 将锁对象放在上下文语法中，进入上下文时，自动执行锁对象的acquire方法（获得锁）
        # 离开上下文时（不管正常还是异常），都会自动执行锁对象的release方法（释放锁）
        with self.lock:
            new_balance = self.balance + amount
            # 用休眠模拟业务受理需要10毫秒时间
            time.sleep(0.01)
            self.balance = new_balance


account = Account()
threads = []
# 创建100个线程，每个线程向账户中转入1元
for _ in range(100):
    t = Thread(target=account.deposit, args=(1, ))
    threads.append(t)
    t.start()
# 等待线程执行结束
for t in threads:
    t.join()
print(f'账户余额: {account.balance}元.')
